package com.kunkun;

import javax.swing.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class MainFrame extends JFrame {

    // 准备一个数组，用来存储数字色块的行列位置，4行4列
    private int[][] imageArray = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 0}
    };
    // 定义两个整数变量记录白色色块的位置
    private int row;
    private int col;

    public int getRow() {
        return row;
    }

    public void setRow(int row) {
        this.row = row;
    }

    public int getCol() {
        return col;
    }

    public void setCol(int col) {
        this.col = col;
    }

    private int count;
    // 定义一个JLabel用于显示移动步数
    private JLabel countLabel;

    // 自定义窗口类，创建对象，展示一个主窗口，使用this
    public MainFrame() {
        // 调用初始化方法,初始化窗口大小信息
        initFrame();
        // 初始化系统菜单，点击弹出菜单信息是退出系统还是重启游戏
        initMenu();
        // 打乱数字色块的顺序
        new Random(this, imageArray);
        // 初始化界面，展示数字色块
        new Image(this, imageArray);
        // 为窗口添加上下左右键监听事件
        initPressKey();
        // 设置窗口可见
        this.setVisible(true);
    }
    private void initFrame() {
        // 设置窗口标题
        this.setTitle("华容道 by kunkun");
        // 设置窗口大小
        this.setSize(465, 575);
        // 设置窗口位置
        this.setLocationRelativeTo(null);
        // 设置窗口关闭方式
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 设置布局方式为绝对位置定位
        this.setLayout(null);
    }

    private void initMenu() {
        JMenuBar menuBar = new JMenuBar(); // 创建菜单栏
        JMenu menu = new JMenu("系统");
        JMenuItem exit = new JMenuItem("退出游戏");
        exit.addActionListener(e -> {
            dispose();
        });
        menu.add(exit);
        JMenuItem restart = new JMenuItem("重新游戏");
        restart.addActionListener(e -> {
            // 重新游戏，重新初始化数组，重新打乱数组，重新初始化界面，定位空白色块的位置
            new Random(this, imageArray);
            new Image(this, imageArray);
            count = 0;
            countLabel.setText("移动步数: " + count);
        });
        menu.add(restart);
        // 将菜单添加到菜单栏中
        menuBar.add(menu);
        // 给菜单栏添加一个展示文字的组件
        countLabel = new JLabel("移动步数: " + count);
        menuBar.add(countLabel);
        // 将菜单栏添加到窗口中
        this.setJMenuBar(menuBar);
    }
    // 监听事件
    private void initPressKey() {
        // 为窗口添加上下左右键监听事件
        this.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {
                // 获取键盘按下的键值
                int keyCode = e.getKeyCode();
                // 判断按下的键值是上下左右键
                switch (keyCode) {
                    case KeyEvent.VK_UP:
                        // 用户按了上键，让图片向上移动
                        move(Direction.UP);
                        break;
                    case KeyEvent.VK_DOWN:
                        move(Direction.DOWN);
                        break;
                    case KeyEvent.VK_LEFT:
                        move(Direction.LEFT);
                        break;
                    case KeyEvent.VK_RIGHT:
                        move(Direction.RIGHT);
                        break;
                }
            }
        });
    }

    // 控制移动
    private void move(Direction r) {
        // 判断图片的方向，进行图片的移动
        boolean moved = false; // 用于标记是否移动成功
        switch (r) {
            case UP:
                // 上交换的条件是行小于3
                if (row < imageArray.length - 1) {
                    // 交换位置
                    int temp = imageArray[row + 1][col];
                    imageArray[row + 1][col] = imageArray[row][col];
                    imageArray[row][col] = temp;
                    // 交换后，行数加1
                    row++;
                    moved = true;
                }
                break;
            case DOWN:
                // 下交换的条件是行大于0
                if (row > 0) {
                    // 交换位置
                    int temp = imageArray[row - 1][col];
                    imageArray[row - 1][col] = imageArray[row][col];
                    imageArray[row][col] = temp;
                    // 交换后，行数减1
                    row--;
                    moved = true;
                }
                break;
            case LEFT:
                // 左交换的条件是列小于3
                if (col < imageArray.length - 1) {
                    // 交换位置
                    int temp = imageArray[row][col + 1];
                    imageArray[row][col + 1] = imageArray[row][col];
                    imageArray[row][col] = temp;
                    // 交换后，列数加1
                    col++;
                    moved = true;
                }
                break;
            case RIGHT:
                // 右交换的条件是列大于0
                if (col > 0) {
                    // 交换位置
                    int temp = imageArray[row][col - 1];
                    imageArray[row][col - 1] = imageArray[row][col];
                    imageArray[row][col] = temp;
                    // 交换后，列数减1
                    col--;
                    moved = true;
                }
                break;
        }
        // 如果移动成功，更新步数和标签
        if (moved) {
            count++;
            handleCorrectMove(countLabel);
        }
        // 重新刷新界面
        new Image(this, imageArray);
    }
    // 更新移动步数的标签
    private void handleCorrectMove(JLabel countLabel) {
        countLabel.setText("移动步数: " + count);
    }
}